package org.nullauthor.allthings.gui.inventory;

import net.minecraft.inventory.Inventories;
import net.minecraft.inventory.Inventory;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.collection.DefaultedList;

public interface DefaultInventory extends Inventory {

    /**
     * 获取物品栏对象
     *
     * @return 物品栏对象
     */
    DefaultedList<ItemStack> getInventory();

    /**
     * 返回物品栏的容量
     *
     * @return 物品栏的大小
     */
    @Override
    default int size() {
        return this.getInventory().size();
    }

    /**
     * 判断物品栏是否为空
     *
     * @return 布尔值，true表示物品栏为空，false表示物品栏不为空
     */
    @Override
    default boolean isEmpty() {
        return this.getInventory().isEmpty();
    }

    /**
     * 清空物品栏，请谨慎操作！
     */
    @Override
    default void clear() {
        this.getInventory().clear();
        this.markDirty();
    }

    /**
     * 根据槽位下标（或称ID）获取指定的物品堆栈
     *
     * @param slot 槽位下标（或称ID）
     * @return 物品堆栈对象
     */
    @Override
    default ItemStack getStack(int slot) {
        return this.getInventory().get(slot);
    }

    /**
     * 根据槽位下标（或称ID）将指定的物品堆栈从物品栏中移除出去
     *
     * @param slot 槽位下标（或称ID）
     * @return 被删除的物品堆栈
     */
    @Override
    default ItemStack removeStack(int slot) {
        ItemStack stack = Inventories.removeStack(this.getInventory(), slot);
        if (!stack.isEmpty()) {
            this.markDirty();
        }
        return stack;
    }

    /**
     * 根据槽位下标（或称ID）以及移除数量将指定的物品堆栈从物品栏中移除出去
     *
     * @param slot   槽位下标（或称ID）
     * @param amount 欲移除的数量
     * @return 被删除的物品堆栈
     */
    @Override
    default ItemStack removeStack(int slot, int amount) {
        ItemStack stack = Inventories.splitStack(this.getInventory(), slot, amount);
        if (!stack.isEmpty()) {
            this.markDirty();
        }
        return stack;
    }

    /**
     * 根据槽位下标（或称ID）向物品栏中设置物品堆栈，该操作可能会向槽位中添加、替换或是补充物品堆栈数量
     *
     * @param slot  槽位下标（或称ID）
     * @param stack 物品堆栈
     */
    @Override
    default void setStack(int slot, ItemStack stack) {
        this.getInventory().set(slot, stack);
        if (stack.getCount() > getMaxCountPerStack()) {
            stack.setCount(getMaxCountPerStack());
        }
        this.markDirty();
    }

    /**
     * 将物品栏状态标记为脏，该方法会在栏位发生任何变化的时候调用，若需要监听物品栏变动以执行某些事件，请重写该方法
     */
    @Override
    default void markDirty() {
    }

    /**
     * 判断给定的玩家实体是否可以使用本物品栏，默认为true，需要特殊判断时请重写该方法
     *
     * @param player 玩家实体
     * @return true为可以使用，false为不可以使用（将不会打开物品栏界面或显示其中的物品）
     */
    @Override
    default boolean canPlayerUse(PlayerEntity player) {
        return true;
    }
}